//###############
//FILE : MyNameServer.java
//WRITER : Daniel Lowengrub, daniel_i_l, 320687098
//EXERCISE : oop ex3 2011
//DESCRIPTION:
//See below
//###############
package oop.ex3.nameserver;


import java.net.UnknownHostException;
import java.util.ArrayList;
import oop.ex3.communication.Communication;
import oop.ex3.communication.Request;
import oop.ex3.communication.RequestThreadDispatcher;
import oop.ex3.communication.SocketAddress;


/**
 * This implements the NameServer as specified in the assignment. It's main job is to open a thread
 * that handles requests from other nameservers. Before that it initializes the thread with a list
 * of requests that it should know how to handle.
 * As a command line argument it gets a port number specifying the port it should listen to.
 * @author daniel
 */
public class MyNameServer {
    private static final int PORT_ARG = 0;
    private static NameServerDatabase _nameServerDatabase;
    private static ArrayList<Request>  _serverRequests;
    private static RequestThreadDispatcher _requestDispatcher;
    private static SocketAddress _address;

    public static void main(String[] args) {
        try {
            initializeServer(args);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
            _requestDispatcher.start();

        try {
            _requestDispatcher.join();
        } catch (InterruptedException ex) {
            return;
            //there shouldn't be any interruptions
        }
    }

    private static void initializeServer(String[] args) throws UnknownHostException {
        _nameServerDatabase = new NameServerDatabase();
        _serverRequests = new ArrayList<Request>();

        int port = Integer.parseInt(args[PORT_ARG]);
        String ip = Communication.getLocalIp();
        _address = new SocketAddress(ip, port);

        initializeRequestDispatcher();

    }
    private static void initializeRequestDispatcher() {
        _requestDispatcher = new RequestThreadDispatcher(_address);

        initializeServerRequests();
        NameServerRequestThread requestThread = new NameServerRequestThread(_serverRequests);

        _requestDispatcher.setBaseThread(requestThread);
    }
    private static void initializeServerRequests() {

        InitializationRequest initRequest = new InitializationRequest(_nameServerDatabase);
        initRequest.addRequest(new RemoveFileRequest(_nameServerDatabase));
        initRequest.addRequest(new WantAllFilesRequest(_nameServerDatabase));
        initRequest.addRequest(new WantServersRequest(_nameServerDatabase));
        initRequest.addRequest(new ContainFileRequest(_nameServerDatabase));
        initRequest.addRequest(new FireRequest(_nameServerDatabase, _requestDispatcher.getServerStatus()));
        initRequest.addRequest(new WantFileRequest(_nameServerDatabase));
        initRequest.addRequest(new GoodByeRequest(_nameServerDatabase));

        _serverRequests.add(initRequest);
    }

}
